home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
vm
/
vmTrace.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-12
|
5KB
|
216 lines
/* vmTrace.c --
*
* Virtual memory tracing routines.
*
* Copyright (C) 1985 Regents of the University of California
* All rights reserved.
*/
#ifndef lint
static char rcsid[] = "$Header: /sprite/src/kernel/vm/RCS/vmTrace.c,v 9.2 90/09/12 13:36:46 shirriff Exp $ SPRITE (Berkeley)";
#endif not lint
#include <sprite.h>
#include <vm.h>
#include <vmInt.h>
#include <vmTrace.h>
#include <mach.h>
#include <sync.h>
#include <sys.h>
#include <stdio.h>
#include <bstring.h>
Sync_Semaphore traceMutex = Sync_SemInitStatic("Vm:traceMutex");
Boolean vm_Tracing = FALSE;
int vmTracesPerClock;
int vmTracesToGo;
char *vmTraceBuffer = (char *)NIL;
int vmTraceFirstByte;
int vmTraceNextByte;
int vmTraceTime = 0;
Fs_Stream *vmTraceFilePtr = (Fs_Stream *)NIL;
Boolean vmTraceDumpStarted = FALSE;
Vm_TraceStats vmTraceStats;
Boolean vmTraceNeedsInit = FALSE;
/*
* ----------------------------------------------------------------------------
*
* VmStoreTraceRec --
*
* Store a trace record into the trace buffer.
*
* Results:
* None.
*
* Side effects:
* Trace buffer modified if the record will fit.
*
* ----------------------------------------------------------------------------
*/
void
VmStoreTraceRec(recType, size, traceRecAddr, checkOverflow)
int recType; /* The type of trace record. */
int size; /* Size of the trace record to dump. */
Address traceRecAddr; /* Trace record to dump. */
Boolean checkOverflow; /* TRUE implies if should check to see if
* should dump the buffer. */
{
short *shortPtr;
MASTER_LOCK(&traceMutex);
Sync_SemRegister(&traceMutex);
if (vmTraceNextByte - vmTraceFirstByte > VM_TRACE_BUFFER_SIZE - size) {
vmTraceStats.traceDrops++;
MASTER_UNLOCK(&traceMutex);
return;
}
if ((vmTraceNextByte & VM_TRACE_BUF_MASK) !=
((vmTraceNextByte + size - 1) & VM_TRACE_BUF_MASK)) {
/*
* We are at the end of the buffer so skip to the end of the
* buffer.
*/
shortPtr = VM_GET_TRACE_BUFFER_PTR(short);
*shortPtr = VM_TRACE_SKIP_REC;
vmTraceNextByte = (vmTraceNextByte + size) & VM_TRACE_BUF_MASK;
if (vmTraceNextByte - vmTraceFirstByte >
VM_TRACE_BUFFER_SIZE - size) {
vmTraceStats.traceDrops++;
MASTER_UNLOCK(&traceMutex);
return;
}
}
if (recType != 0) {
short *shortPtr;
shortPtr = (short *)traceRecAddr;
*shortPtr = recType;
}
bcopy(traceRecAddr, VM_GET_TRACE_BUFFER_PTR(char), size);
vmTraceNextByte += size;
if (checkOverflow) {
if (vmTraceNextByte - vmTraceFirstByte > VM_TRACE_BUFFER_SIZE / 2 &&
!vmTraceDumpStarted) {
vmTraceDumpStarted = TRUE;
Proc_CallFunc(VmTraceDump, (ClientData)0, 0);
}
}
MASTER_UNLOCK(&traceMutex);
}
/*
*----------------------------------------------------------------------
*
* VmTraceDump --
*
* Daemon to dump virtual memory trace records to a file.
*
* Results:
* None.
*
* Side effects:
* Page freed.
*
*----------------------------------------------------------------------
*/
/* ARGSUSED */
void
VmTraceDump(data, callInfoPtr)
ClientData data;
Proc_CallInfo *callInfoPtr;
{
int curNextByte;
int length;
int savedLength;
ReturnStatus status;
vmTraceStats.traceDumps++;
/*
* Dump the trace buffer.
*/
curNextByte = vmTraceNextByte;
while (vmTraceFirstByte != curNextByte) {
length = VM_TRACE_BUFFER_SIZE - VM_GET_BUFFER_INDEX(vmTraceFirstByte);
if (curNextByte - vmTraceFirstByte < length) {
length = curNextByte - vmTraceFirstByte;
}
savedLength = length;
status = Fs_Write(vmTraceFilePtr,
vmTraceBuffer + VM_GET_BUFFER_INDEX(vmTraceFirstByte),
vmTraceFirstByte, &length);
if (status != SUCCESS) {
printf("%s VmTraceDaemon: Couldn't write trace file, reason %x\n",
"Warning:", status);
break;
} else if (length != savedLength) {
printf("Warning: VmTraceDaemon: Short write, length = %d\n",
length);
break;
}
vmTraceFirstByte += length;
}
vmTraceDumpStarted = FALSE;
}
/*
*----------------------------------------------------------------------
*
* VmCheckTraceOverflow --
*
* Dump the trace buffer if it is about to overflow.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
VmCheckTraceOverflow()
{
MASTER_LOCK(&traceMutex);
if (vmTraceNextByte - vmTraceFirstByte > VM_TRACE_BUFFER_SIZE / 2 &&
!vmTraceDumpStarted) {
vmTraceDumpStarted = TRUE;
Proc_CallFunc(VmTraceDump, (ClientData)0, 0);
}
MASTER_UNLOCK(&traceMutex);
}
/*
*----------------------------------------------------------------------
*
* Vm_StoreTraceTime --
*
* Write a trace time stamp.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Vm_StoreTraceTime(timeStamp)
Timer_Ticks timeStamp;
{
Vm_TraceTimeStamp timeStampRec;
bcopy((Address)&timeStamp, (Address)&timeStampRec.time,
sizeof(timeStampRec.time));
VmStoreTraceRec(VM_TRACE_TIME_REC, sizeof(timeStampRec),
(Address)&timeStampRec, TRUE);
}